package com.example.tongyao.system.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.tongyao.system.entity.*;
import com.example.tongyao.system.message.SystemMessage;
import com.example.tongyao.system.service.ISysDeptMenuService;
import com.example.tongyao.system.service.ISysInterfaceService;
import com.example.tongyao.system.service.ISysMenuService;
import com.example.tongyao.system.service.ISysRoleMenuService;
import com.example.tongyao.utils.DataResult;
import com.example.tongyao.utils.DateUtils;
import com.example.tongyao.utils.StringUtils;
import com.example.tongyao.utils.token.UserUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.util.*;

/**
 * <p>
 * 菜单表 前端控制器
 * </p>
 *
 * @author tongyao
 * @since 2021-08-18
 */
@RestController
@Api(tags = "系统_菜单前端控制器")
@RequestMapping("/system/sys-menu")
public class SysMenuController {

    @Resource
    private ISysMenuService iSysMenuService;

    @Resource
    private ISysDeptMenuService iSysDeptMenuService;

    @Resource
    private ISysInterfaceService iSysInterfaceService;

    @Resource
    private ISysRoleMenuService iSysRoleMenuService;

    boolean reuslt;

    Map<String,Object> map;

    /**
     * 分页查询所有菜单
     * @return
     */
    @ApiOperation(
            value = "查询菜单",
            notes = "分页查询所有菜单",
            httpMethod = "GET")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "menuName",value = "菜单名称"),
            @ApiImplicitParam(name = "pageNo",value = "当前页数",defaultValue = "1"),
            @ApiImplicitParam(name = "pageSize",value = "显示条数",defaultValue = "10"),
            @ApiImplicitParam(name = "sortBy",value = "排序字段（多个以英文逗号拼接）",defaultValue = "create_time"),
            @ApiImplicitParam(name = "order",value = "排序类型",defaultValue = "asc")
    })
    @GetMapping(value = "/page" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult page(
            @RequestParam(required = false) String menuName,
            @RequestParam(defaultValue = "1") int pageNo,
            @RequestParam(defaultValue = "10") int pageSize,
            @RequestParam(defaultValue = "create_time") String sortBy,
            @RequestParam(defaultValue = "asc") String order) {

        LambdaQueryWrapper<SysMenu> sysMenuLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if(StringUtils.isNotBlank(menuName)){
            sysMenuLambdaQueryWrapper.like(SysMenu::getMenuName,menuName);
        }

        sysMenuLambdaQueryWrapper.eq(SysMenu::getDelFlag,"1");
        sysMenuLambdaQueryWrapper.last(" order by "+sortBy+" "+order);

        Page<SysMenu> page = new Page<>(pageNo,pageSize);
        IPage<SysMenu> iPage = iSysMenuService.page(page,sysMenuLambdaQueryWrapper);

        List<SysMenu> sysMenuList = SysMenuController.showMenu(iPage.getRecords());
        iPage.setRecords(sysMenuList);
        return DataResult.setSuccess(iPage);
    }

    @ApiOperation(
            value = "增加菜单",
            notes = "增加一个菜单",
            httpMethod = "POST")
    @PostMapping(value = "/save" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult save(@Valid @RequestBody SysMenu sysMenu) {
        SysUser user = (SysUser) UserUtils.getUserInfo();
        sysMenu.setMenuEnabled(true);
        sysMenu.setDelFlag(1);
        sysMenu.setCreateBy(user.getUserId());
        sysMenu.setCreateTime(DateUtils.getDateTime());

        reuslt = iSysMenuService.save(sysMenu);
        if(!reuslt){
            throw new RuntimeException(SystemMessage.menu+SystemMessage.add+SystemMessage.fail+SystemMessage.a);
        }
        return DataResult.setSuccess(null);
    }

    @ApiOperation(
            value = "编辑菜单",
            notes = "编辑一个菜单",
            httpMethod = "PUT")
    @PutMapping(value = "/edit" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult edit(@Valid @RequestBody SysMenu sysMenu) {
        SysUser user = (SysUser) UserUtils.getUserInfo();

        LambdaUpdateWrapper<SysMenu> sysMenuLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        if(StringUtils.isNotBlank(sysMenu.getMenuIcon())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuIcon,sysMenu.getMenuIcon());
        }
        if(StringUtils.isNotBlank(sysMenu.getMenuName())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuName,sysMenu.getMenuName());
        }
        if(StringUtils.isNotBlank(sysMenu.getMenuPath())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuPath,sysMenu.getMenuPath());
        }
        if(StringUtils.isNotBlank(sysMenu.getMenuType())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getMenuType,sysMenu.getMenuType());
        }
        if(StringUtils.isNotBlank(sysMenu.getOpenType())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getOpenType,sysMenu.getOpenType());
        }/*else if(StringUtils.isNotBlank(sysMenu.getMenuIcon())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getParentId,sysMenu.getParentId());

        }*/

        if(StringUtils.isNotBlank(sysMenu.getPermission())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getPermission,sysMenu.getPermission());
        }
        if(StringUtils.isNotNull(sysMenu.getSort())){
            sysMenuLambdaUpdateWrapper.set(SysMenu::getSort,sysMenu.getSort());
        }

        sysMenuLambdaUpdateWrapper.set(SysMenu::getModifyBy,user.getUserId());
        sysMenuLambdaUpdateWrapper.set(SysMenu::getModifyTime,DateUtils.getDateTime());

        sysMenuLambdaUpdateWrapper.eq(SysMenu::getMenuId,sysMenu.getMenuId());

        reuslt = iSysMenuService.update(sysMenuLambdaUpdateWrapper);
        if(!reuslt){
            throw new RuntimeException(
                    SystemMessage.menu+
                            SystemMessage.update+
                            SystemMessage.fail+
                            SystemMessage.a);
        }
        return DataResult.setSuccess(null);
    }

    @ApiOperation(
            value = "删除菜单",
            notes = "删除一个或多个菜单",
            httpMethod = "DELETE")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "menuId",value = "菜单编号，多个以英文逗号拼接",required = true),
    })
    @DeleteMapping(value = "/delete" , produces = {MediaType.APPLICATION_JSON_VALUE})
    public DataResult delete(@RequestParam String menuId) {
        List menuIds = Arrays.asList(menuId.split(","));

        for (Object menu: menuIds) {
            //删除菜单
            LambdaUpdateWrapper<SysMenu> sysMenuLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            sysMenuLambdaUpdateWrapper
                    .set(SysMenu::getDelFlag,"0")
                    .eq(SysMenu::getMenuId,menu);

            reuslt = iSysMenuService.update(sysMenuLambdaUpdateWrapper);
            if(!reuslt){
                throw new RuntimeException(
                        SystemMessage.menu+
                                SystemMessage.delete+
                                SystemMessage.fail+
                                SystemMessage.a
                );
            }

            //删除菜单关系

            //部门菜单关系
            map = new HashMap<>();
            map.put("menu_id",menu);
            iSysDeptMenuService.removeByMap(map);

            //菜单接口关系
            map = new HashMap<>();
            map.put("menu_id",menu);
            LambdaUpdateWrapper<SysInterface> sysInterfaceLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
            sysInterfaceLambdaUpdateWrapper
                    .set(SysInterface::getDelFlag,"0")
                    .eq(SysInterface::getMenuId,menu);
            iSysInterfaceService.update(sysInterfaceLambdaUpdateWrapper);

            //角色菜单关系
            map = new HashMap<>();
            map.put("menu_id",menu);
            iSysRoleMenuService.removeByMap(map);
        }
        return DataResult.setSuccess(null);
    }

    /**
     * 调整菜单的上下级
     *
     * @param menuList 菜单
     * @return
     */
    public static List<SysMenu> showMenu(List<SysMenu> menuList) {
        List<SysMenu> nodeList = new ArrayList<SysMenu>();
        for (SysMenu menu : menuList) {
            boolean isChildMark = false;
            for (SysMenu sysMenu : menuList) {
                if (menu.getParentId() != null && menu.getParentId().equals(sysMenu.getMenuId())) {
                    isChildMark = true;
                    if (sysMenu.getChildren() == null) {
                        sysMenu.setChildren(new ArrayList<SysMenu>());
                    }
                    sysMenu.getChildren().add(menu);
                    break;
                }
            }
            if (!isChildMark) {
                nodeList.add(menu);
            }
        }
        return nodeList;
    }
}
